#include<iostream>
#include<mutex>
#include<memory>
// class Lock
// {
//     public:
//         explicit Lock(std::mutex* mutex)
//         :_mutex(mutex)
//         {
//             _mutex->lock();
//         }
//         ~Lock()
//         {
//             _mutex->unlock();
//         }
//     private:
//         std::mutex* _mutex;
// };
//Lock 继承 Uncopyable类
// class Uncopyable
// {
//     protected: 
//         Uncopyable()
//         {}
//         ~Uncopyable()
//         {}
//     private:
//         Uncopyable(const Uncopyable&); //阻止copy
//         Uncopyable& operator=(const Uncopyable&);
// };
// class Lock: public Uncopyable
// {
//     public:
//     explicit Lock(std::mutex* mutex)
//         :_mutex(mutex)
//         {
//             _mutex->lock();
//         }
//         ~Lock()
//         {
//             _mutex->unlock();
//         }
//     private:
//         std::mutex* _mutex;
// };

//测试引用计数
class Lock
{
    public:
    explicit Lock(std::mutex* _mutex_)
    :mutex_ptr(_mutex_,[](std::mutex* m){if(m) m->unlock();})//当引用次数为0时调用unlock函数
    {
        if(mutex_ptr)
            mutex_ptr->lock();
    }
    Lock(const Lock&) = delete;
    Lock& operator=(const Lock&) = delete;
    private:
    std::shared_ptr<std::mutex> mutex_ptr; //采用
};


void test_mutex()
{
    std::mutex _m;
    // std::mutex & _mutex = _m;
    
    Lock m11(&_m);
    Lock m12(m11);//此时会发生错误
    //解决方案:1. 禁止复制
    //即继承Uncopyable类

    //2. 对底层资源祭出(引用计数)

}
int main()
{   
    test_mutex();
    return 0;
}

// 总结:复制RAII对象时,必须复制它管理的对象,所以资源的拷贝行为决定了RAII对象copy行为
//普遍的而常见的RAII class copying行为,抑制copying,施行引用计数法, 